#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<set>
#include<queue>
#include<functional>
using namespace std;

class node{
public:
    node(int i,int j){
        this->i = i;
        this->j = j;
    }
public:
    int i;
    int j;
};

class edge{
public:
    edge(int val,node* start,node* end){
        this->val = val;
        this->end = start;
        this->end = end;
    }
public:
    int val;
    node* start;
    node* end;
};

class compare{
public:
    bool operator()(edge* e1, edge* e2){
        return e1->val>e2->val;
    }
};



class Solution {
public:
    int minCostConnectPoints(vector<vector<int>>& points) {
        int result=0;
        //最小生成树的生成，使用prim算法
        set<pair<int,int>> S;
        priority_queue<edge*,vector<edge*>,compare> Q;
        node* start = new node(points[0][0],points[0][1]);
        S.insert(make_pair(points[0][0],points[0][1]));
        for(int i = 1;i<points.size();++i){
                node* end = new node(points[i][0],points[i][1]);
                edge* edg = new edge(abs(start->i-end->i)+abs(start->j-end->j),start,end);
                Q.push(edg);
            }
        while(!Q.empty()){
            edge* e1 = Q.top();
            Q.pop();
            if(S.insert(make_pair(e1->end->i,e1->end->j)).second==true){
                result+=e1->val;
                for(int i =0;i<points.size();++i){
                    if(S.find(make_pair(points[i][0],points[i][1]))==S.end()){
                        node* end = new node(points[i][0],points[i][1]);
                        edge* edg = new edge(abs(e1->end->i-end->i)+abs(e1->end->j-end->j),e1->end,end);
                        Q.push(edg);
                    }
                }
            }
        }
        return result;
    }

};



int main(){
    Solution S;
    vector<vector<int>> points = {{3,12},{-2,5},{-4,1}};
    cout<<S.minCostConnectPoints(points)<<endl;
}